"""
为了方便处理，对模拟数据按以下规则转换为数值型列表数据：
年龄：<30赋值为0；30-40赋值为1；>40赋值为2
收入：低为0；中为1；高为2
工作性质：不稳定为0；稳定为1
信用评级：差为0；好为1
"""
# 创建数据集
def createdataset():
    dataSet = [[0, 2, 0, 0, 'N'],
                [0, 2, 0, 1, 'N'],
                [1, 2, 0, 0, 'Y'],
                [2, 1, 0, 0, 'Y'],
                [2, 0, 1, 0, 'Y'],
                [2, 0, 1, 1, 'N'],
                [1, 0, 1, 1, 'Y'],
                [0, 1, 0, 0, 'N'],
                [0, 0, 1, 0, 'Y'],
                [2, 1, 1, 0, 'Y'],
                [0, 1, 1, 1, 'Y'],
                [1, 1, 0, 1, 'Y'],
                [1, 2, 1, 0, 'Y'],
                [2, 1, 0, 1, 'N'], ]
    labels = ['age',  'income',  'job',  'credit']
    return dataSet,  labels

ds1, lab = createdataset()
print(ds1)
print(lab)

# 计算样本数据集分类标签为Y/N的概率
# dataset为样本数据和分类结果；cls_val是分类字符，Y/N
def prob(dataset,  cls_val):
    cnt = 0.0
    for e in dataset:
        if e[4] == cls_val:
            cnt += 1
    res = cnt/len(dataset)
    return res


py = prob(ds1,  'Y')
print("分类为Y的概率：",  py)
pn = prob(ds1,  'N')
print("分类为N的概率：",  pn)


# 计算条件概率
# dataset为样本数据和分类结果；cls_val是分类字符，Y/N；attr_index是属性的序号；attr_val是属性的取值
def conditionp(dataset,  cls_val,  attr_index,  attr_val):
    cnt1 = 0.0
    cnt2 = 0.0
    for e in dataset:
        if e[4] == cls_val:
            cnt1 += 1
            if e[attr_index] == attr_val:
                cnt2 += 1
    return cnt2/cnt1


print("计算分类为Y时，age属性三个取值的条件概率：")
pa0y = conditionp(ds1, 'Y', 0, 0)
print("条件概率P(age<30|Y) = ", pa0y)
pa1y = conditionp(ds1, 'Y', 0, 1)
print("条件概率P(30<=age<=40|Y) = ", pa1y)
pa2y = conditionp(ds1, 'Y', 0, 2)
print("条件概率P(age>40|Y) = ", pa2y)


# 利用后验概率计算先验概率
# dataset为样本数据和分类结果；testlist是新样本数据列表；cls_y、cls_n是分类字符，Y/N；
def nb(dataset, testlist, cls_y, cls_n):
        py = prob(dataset, cls_y)
        pn = prob(dataset, cls_n)

        for i, val in enumerate(testlist):
                py = py*conditionp(dataset, cls_y, i, val)
                pn = pn*conditionp(dataset, cls_n, i, val)
        return py, pn


tsvec = [0, 0, 1, 1]
[prob, probs] = nb(ds1, tsvec, 'Y', 'N')
print("测试结果：", prob)
tsvec1 = [0, 2, 0, 1]
[prob1, prob1s] = nb(ds1, tsvec1, 'Y', 'N')
print("测试结果1：", prob1)
